package model

import (
	"Three/project01/chatroom/common/message"
	"encoding/json"
	"fmt"
	"github.com/gomodule/redigo/redis"
)

//我们在服务器启动时，就初始一个userDao实例
//把它做成全局的变量，在需要和redis操作是，就直接使用
var (
	MyUserDao *UserDao
)

//定义一个userdao的结构体，完成对user结构体的各种操作

type UserDao struct {
	pool *redis.Pool
}

//使用工厂模式，创建一个userDao实例
func NewUserDao(pool *redis.Pool) (userDao *UserDao) {
	userDao = &UserDao{
		pool: pool,
	}
	return
}

//思考一下UserDao应该提供哪些方法给我们
//1，根据用户id返回一个user实例+err
func (this *UserDao) getUserById(conn redis.Conn, id int) (user *User, err error) {

	//通过给定的id去redis查询这个用户
	res, err := redis.String(conn.Do("HGet", "users", id))
	if err != nil {
		if err == redis.ErrNil { //表示在user哈希中没有找到对应的id
			err = ERROR_USER_NOTEXISTS
		}
		return
	}

	//user = &User{}     ??
	//err = json.Unmarshal([]byte(res),user)  	??
	//这里我们需要把res反序列化成User实例
	err = json.Unmarshal([]byte(res), &user)
	if err != nil {
		fmt.Println("json.Unmarshal err=", err)
		return
	}
	return
}

//完成登录的校验Login
//1，Login完成对用户的验证
//2，如果用户的id和pwd都正确则返回一个user实例
//3，如果用户的id和pwd有错误则返回对应的错误信息
func (this *UserDao) Login(userId int, userPwd string) (user *User, err error) {

	//先从UserDao的连接池中取出一根连接
	conn := this.pool.Get() //(*(*this).pool).Get()
	defer conn.Close()
	user, err = this.getUserById(conn, userId)
	if err != nil {
		return
	}
	//证明用户密码正确
	if user.UserPwd != userPwd {
		err = ERROR_USER_PWD
		return
	}
	return
}

func (this *UserDao) Register(user *message.User) (err error) {

	//先从UserDao的连接池中取出一根连接
	conn := (*(*this).pool).Get()
	defer conn.Close()
	_, err = this.getUserById(conn, user.UserId)
	if err == nil {
		err = ERROR_USER_EXISTS
		return
	}
	//这时，说明该id在redis中没有，则可以完成注册
	data, err := json.Marshal(user) //序列化
	if err != nil {
		return
	}
	//入库
	_, err = conn.Do("HSet", "users", user.UserId, string(data))
	if err != nil {
		fmt.Println("保存注册用户信息出错 err=", err)
		return
	}
	return
}
